//
//  Copyright 2015 XiaoJSoft Studio.
//  Copyright 2015 Harbin Institute of Technology(HIT), Software Engineering Department.
//
//  Use of this source code is governed by a proprietary license. You can not read, change or
//  redistribute this source code unless you have a written authorization from the copyright
//  holder listed above.
//

#include "manifest.h"
#include "json/json.h"

namespace ui {
namespace compiler {

Manifest::Manifest() : m_Dependencies(),
                       m_Sources(),
                       m_Stylesheets(),
                       m_PreRun(""),
                       m_PostRun("") {
    //  Dummy
}

Manifest::~Manifest() {
    //  Dummy
}

std::string Manifest::getPreRunScript() {
    return this->m_PreRun;
}

std::string Manifest::getPostRunScript() {
    return this->m_PostRun;
}

void Manifest::getDependencies(std::vector<std::string> &target) {
    target = this->m_Dependencies;
}

void Manifest::getSources(std::vector<std::string> &target) {
    target = this->m_Sources;
}

void Manifest::getStylesheets(std::vector<std::string> &target) {
    target = this->m_Stylesheets;
}

bool Manifest::loadString(const std::string &data) {
    Json::Reader reader;
    Json::Value root;

    //  Parse the origin data.
    if (!reader.parse(data, root, false)) {
        return false;
    }

    //  Check root node type.
    if (!root.isObject()) {
        return false;
    }

    //  Read sources, dependencies and styles.
    Json::Value raw_sources = root["sources"],
                raw_dependencies = root["dependencies"],
                raw_styles = root["styles"];

    //  Clear saved sources.
    this->m_Sources.clear();

    if (!raw_sources.isNull()) {
        //  Check object type.
        if (!raw_sources.isArray()) {
            return false;
        }

        //  Load each item.
        for (unsigned int idx = 0; idx < raw_sources.size(); ++idx) {
            Json::Value item = raw_sources[idx];

            //  Check item type.
            if (!item.isString()) {
                return false;
            }

            //  Convert and add the item.
            this->m_Sources.push_back(item.asString());
        }
    }

    //  Clear saved dependencies.
    this->m_Dependencies.clear();

    if (!raw_dependencies.isNull()) {
        //  Check object type.
        if (!raw_dependencies.isArray()) {
            return false;
        }

        //  Load each item.
        for (unsigned int idx = 0; idx < raw_dependencies.size(); ++idx) {
            Json::Value item = raw_dependencies[idx];

            //  Check item type.
            if (!item.isString()) {
                return false;
            }

            //  Convert and add the item.
            this->m_Dependencies.push_back(item.asString());
        }
    }

    //  Clear saved stylesheets.
    this->m_Stylesheets.clear();

    if (!raw_styles.isNull()) {
        //  Check object type.
        if (!raw_styles.isArray()) {
            return false;
        }

        //  Load each item.
        for (unsigned int idx = 0; idx < raw_styles.size(); ++idx) {
            Json::Value item = raw_styles[idx];

            //  Check item type.
            if (!item.isString()) {
                return false;
            }

            //  Convert and add the item.
            this->m_Stylesheets.push_back(item.asString());
        }
    }

    //  Read pre-run and post-run scripts.
    Json::Value pre_run = root["pre_run"], post_run = root["post_run"];

    //  Load the pre-run script.
    if (!pre_run.isNull()) {
        //  Check object type.
        if (!pre_run.isString()) {
            return false;
        }

        //  Convert and load.
        this->m_PreRun = pre_run.asString();
    } else {
        this->m_PreRun = "";
    }

    //  Load the post-run script.
    if (!post_run.isNull()) {
        //  Check object type.
        if (!post_run.isString()) {
            return false;
        }

        //  Convert and load.
        this->m_PostRun = post_run.asString();
    } else {
        this->m_PostRun = "";
    }

    return true;
}

}  //  namespace compiler
}  //  namespace ui
